import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.xml.parsers.ParserConfigurationException;

import nu.xom.Attribute;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.IllegalNameException;

import org.xml.sax.SAXException;

public class GUIConceptPanel extends JFrame implements TableModelListener {
	// private JScrollPane scrollPane;
	private JScrollPane buttonPane;
	private JTabbedPane tabbedPane;
	private JSplitPane splitPane;
	private JPanel cPanel;
	private JPanel buttonPanel;
	private JTable conceptTable;
	private JButton loadButton;
	private JButton saveButton;
	private JButton addRowButton;
	private JButton deleteRow;
	private JButton loadConcept;
	private JFileChooser xmlFileChooser;
	private static String xmlFilePath;
	private File xmlFileToOpen;
	// private static String [][] tableData ;
	private static String[] columnNames = { "Concept Name", "Name",
			"Unique ID", "Hwnd", "Class", "Style", "ExtStyle", "Role",
			"Alt Name" };
	private static List dataList = new ArrayList();
	private JComboBox combo;
	//private GuiObjectDataModel dataModel;
	private JCheckBox checkBox;
	public static Object[][] tableData;

	public GUIConceptPanel() {

		setTitle("MOATS");
		setSize(700, 700);

		cPanel = new JPanel();
		cPanel.setLayout(new BorderLayout());
		getContentPane().add(cPanel);
		String tableData[][] = new String[dataList.size()][2];

		conceptTable = new JTable(tableData, columnNames);
		conceptTable.getModel().addTableModelListener(this);

		// File Chooser Button
		loadButton = new JButton();
		loadButton.setVisible(true);
		loadButton.setText("Select XML File");

		// File save Button
		saveButton = new JButton();
		saveButton.setVisible(false);
		saveButton.setText("Save Mappings");

		// Roww Add Button
		addRowButton = new JButton();
		addRowButton.setVisible(false);

		// Delete Row Button
		deleteRow = new JButton();
		deleteRow.setVisible(false);
		
		//Load Concept XML
		loadConcept = new JButton();
		loadConcept.setText("Load Concept XML");
		loadConcept.setVisible(true);
		
		// Action Listener for Save Mappings button
		final JFileChooser saveLocationChooser = new JFileChooser();
		saveButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {

				try {
					int option = saveLocationChooser
							.showSaveDialog(GUIConceptPanel.this);
					if (option == JFileChooser.APPROVE_OPTION) {
						if (saveLocationChooser.getSelectedFile() != null) {
							File theFileToSave = saveLocationChooser
									.getSelectedFile();
							saveMappings(theFileToSave);
						}
					}
				} catch (IOException e1) {
					
					e1.printStackTrace();
					System.out.println(e1.getMessage());
				} catch (IllegalNameException e2) {
					
					e2.printStackTrace();
				} catch (ParserConfigurationException f) {
					
					f.printStackTrace();
				} catch (SAXException g) {
					g.printStackTrace();
				}

			}

		});

		// add button to the panel
		buttonPanel = new JPanel();
		buttonPanel.add(loadConcept);
		buttonPanel.add(loadButton);
	
		// add the save button to the panel
		buttonPanel.add(saveButton);
		buttonPanel.add(addRowButton);
		buttonPanel.add(deleteRow);
		
 final	JFileChooser conceptXMLFileChooser = new JFileChooser();
		loadConcept.addActionListener(new ActionListener()
		{

			@Override
			public void actionPerformed(ActionEvent arg0) {
				int returnval = conceptXMLFileChooser
				.showOpenDialog(GUIConceptPanel.this);

		if (returnval == JFileChooser.APPROVE_OPTION)
				{
					xmlFileToOpen = conceptXMLFileChooser.getSelectedFile();
			 
				}
				
			}
			
		});
		
		
		// Create the File Chooser to select the xml files
		xmlFileChooser = new JFileChooser();
		// Action Listener for Select XML File button
		loadButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				int returnval = xmlFileChooser
						.showOpenDialog(GUIConceptPanel.this);

				if (returnval == JFileChooser.APPROVE_OPTION) {
					File xmlFileToOpen = xmlFileChooser.getSelectedFile();

					//String xmlPath = xmlFileToOpen.getName();
					getTableData(xmlFileToOpen);

				}

			}

		});
		JScrollPane scrollPane = new JScrollPane(conceptTable);
		scrollPane.setMinimumSize(new Dimension(100, 200));

		buttonPane = new JScrollPane(buttonPanel);

		buttonPane.setMinimumSize(new Dimension(50, 200));

		splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane,
				buttonPane);
		splitPane.setOneTouchExpandable(true);
		splitPane.setDividerLocation(500);
		// cPanel.add(splitPane, BorderLayout.CENTER);
		XMLTreeFrame nf = new XMLTreeFrame();
		nf.parser();
		CodeEditor ce = new CodeEditor();

		tabbedPane = new JTabbedPane();
		tabbedPane.addTab("xml Panel", nf.topPanel);
		tabbedPane.addTab("Code Editor", ce.editorPanel);
		tabbedPane.addTab("Concept Panel", splitPane);

		cPanel.add(tabbedPane);

	}
	
	/*  This method is used to setup the editor for the concept 
	 * column of the Concept Table.
	 */
	
	public void setupConceptColumn(JTable table, TableColumn column)
			throws ParserConfigurationException, SAXException, IOException {
		{
			// TableColumn column = conceptTable.getColumnModel().getColumn(0);
			// Set up the editor for the sport cells.
			JComboBox comboBox = new JComboBox();

			ConceptNameXMLParser cnxp = new ConceptNameXMLParser();

			cnxp.parseXML( xmlFileToOpen);
			for (int i = 0; i < cnxp.conceptNameList.size(); i++) {
				comboBox.addItem(cnxp.conceptNameList.get(i));
			}

			column.setCellEditor(new DefaultCellEditor(comboBox));

			// Set up tool tips for the sport cells.
			DefaultTableCellRenderer renderer = new DefaultTableCellRenderer();
			renderer.setToolTipText("Click for Concept Names");
			column.setCellRenderer(renderer);
		}

	}
	
	/*  This method is used to setup the editor for the alternate name 
	 * column of the Concept Table.
	 */

	public void setupAltNameColumn(JTable table, TableColumn column) {
		{
			// TableColumn column = conceptTable.getColumnModel().getColumn(0);
			// Set up the editor for the sport cells.

			JTextField textBox = new JTextField();

			column.setCellEditor(new DefaultCellEditor(textBox));

			
		}

	}
	 /*
     * This method picks good column sizes.
     */

	private void initColumnSizes(JTable table) {
		DefaultTableModel model = (DefaultTableModel) table.getModel();
		TableColumn column = null;
		Component comp = null;
		int headerWidth = 0;
		int cellWidth = 0;
		// Object[] longValues = model..longValues;
		TableCellRenderer headerRenderer = table.getTableHeader()
				.getDefaultRenderer();

		for (int i = 0; i < 8; i++) {
			column = table.getColumnModel().getColumn(i);

			comp = headerRenderer.getTableCellRendererComponent(null, column
					.getHeaderValue(), false, false, 0, 0);
			headerWidth = comp.getPreferredSize().width;

			comp = table.getDefaultRenderer(model.getColumnClass(i))
					.getTableCellRendererComponent(table, columnNames[i],
							false, false, 0, i);
			cellWidth = comp.getPreferredSize().width;

			if (false) {
				System.out.println("Initializing width of column " + i + ". "
						+ "headerWidth = " + headerWidth + "; cellWidth = "
						+ cellWidth);
			}

			column.setPreferredWidth(Math.max(headerWidth, cellWidth));
		}
	}
	
	/* Method for loading the data into the concept table 
	 * on the selection of the state xml
	 */

	@SuppressWarnings("static-access")
	public void getTableData(File fileToOpen) { 
		
		if(xmlFileToOpen == null)
		{
			JOptionPane.showMessageDialog(null, "please select a concept xml first" , "Error",JOptionPane.INFORMATION_MESSAGE);
		}
		else
		{
		TestClassData td = new TestClassData();
		td.fileToOpen = fileToOpen;
		
		ConceptXMLParser cxp = new ConceptXMLParser();
		final GUITestScriptPanel newFrame = new GUITestScriptPanel();
		cxp.dataList.clear();

		td.createDataLists();

		int dataSize = cxp.dataList.size() / 8;
		
		tableData = new Object[dataSize][9];

		// System.out.println(td.nameList.get(1));

		for (int i = 0; i < (dataSize); i++) {
			tableData[i][0] = "Select Concept Name";
			tableData[i][1] = td.nameList.get(i);
			tableData[i][2] = td.uniqueIDList.get(i);
			tableData[i][3] = td.hwndList.get(i);
			// tableData[i][3] = td.locationList.get(i);
			tableData[i][4] = td.objectClassList.get(i);
			tableData[i][5] = td.styleList.get(i);
			tableData[i][6] = td.extStyleList.get(i);
			tableData[i][7] = td.roleList.get(i);
			tableData[i][8] = "";

		}

		// GuiObjectDataModel dataModel = new GuiObjectDataModel();
		final DefaultTableModel model = new DefaultTableModel();

		// addColumns(columnNames);
		model.setDataVector(tableData, columnNames);

		conceptTable = new JTable(model);
		conceptTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);

		conceptTable.getModel().addTableModelListener(this);
		try {
			setupConceptColumn(conceptTable, conceptTable.getColumnModel()
					.getColumn(0));
		} catch (ParserConfigurationException e1) {
			
			e1.printStackTrace();
		} catch (SAXException e1) {
			
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		setupAltNameColumn(conceptTable, conceptTable.getColumnModel()
				.getColumn(8));

		
		JScrollPane scrollPane = new JScrollPane(conceptTable);

		
		tabbedPane.remove(splitPane);

		
		scrollPane.setMinimumSize(new Dimension(100, 200));
		saveButton.setVisible(true);
		// addRowButton = new JButton();
		addRowButton.setVisible(true);
		addRowButton.setText("Add row");

		// deleteRow = new JButton();
		deleteRow.setVisible(true);
		deleteRow.setText("Delete row");
		addRowButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
			
				
				int rowno = conceptTable.getSelectedRow();
				if(rowno<0)
				{
					JOptionPane.showMessageDialog(null, "please select a row to add" , "Error",JOptionPane.INFORMATION_MESSAGE);
				}
				//System.out.println(rowno);
				else
				{
				model.insertRow(rowno, new Object[] {
						conceptTable.getValueAt(rowno, 0),
						conceptTable.getValueAt(rowno, 1),
						conceptTable.getValueAt(rowno, 2),
						conceptTable.getValueAt(rowno, 3),
						conceptTable.getValueAt(rowno, 4),
						conceptTable.getValueAt(rowno, 5),
						conceptTable.getValueAt(rowno, 6),
						conceptTable.getValueAt(rowno, 7),
						conceptTable.getValueAt(rowno, 8) });

				}

			}

		});

		deleteRow.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				int rowno = conceptTable.getSelectedRow();
				if(rowno<0)
				{
					JOptionPane.showMessageDialog(null, "please select a row to delete" , "Error",JOptionPane.INFORMATION_MESSAGE);
				}
				else
				{
				model.removeRow(rowno);
				}
			}

		});
		// buttonPanel.add(addRowButton);
		// buttonPanel.add(deleteRow);

		buttonPane = new JScrollPane(buttonPanel);

		buttonPane.setMinimumSize(new Dimension(50, 200));

		splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, scrollPane,
				buttonPane);
		// scrollPane.repaint();

		splitPane.setOneTouchExpandable(true);
		splitPane.setDividerLocation(500);
		// cPanel.add(splitPane, BorderLayout.CENTER);
		tabbedPane.add("Concept Panel", splitPane);
		tabbedPane.setSelectedIndex(2);
		// cPanel.repaint();
		}
	}


	/*
	 * Method for saving the concepts and GUI Objects mapping
	 * to an XML on clicking the Save Mappings Button
	 */
	@SuppressWarnings("static-access")
	public void saveMappings(File xmlFile) throws IOException,
			IllegalNameException, ParserConfigurationException, SAXException {
		
		ConceptXMLParser cxp = new ConceptXMLParser();
		ConceptNameXMLParser cnxp = new ConceptNameXMLParser();
		cnxp.parseXML( xmlFileToOpen);
		int length = cnxp.conceptNameList.size();

		for (int i = 0; i < length; i++) {
			System.out.println(cnxp.conceptNameList.get(i));
		}
		TestClassData td = new TestClassData();

		// Element root = new Element("Mappings");
		Element root = new Element("MapConcepts");
		Element GUIObjects = new Element("GUIObjects");
		Attribute domainName = new Attribute("id", cnxp.domainName);
		GUIObjects.addAttribute(domainName);
		root.appendChild(GUIObjects);
		System.out.println(conceptTable.getRowCount());
		for (int i = 0; i < (cxp.dataList.size() / 8); i++) {
			// append the GUIObjects name to the root
			Element GUIObject = new Element("GUIObject");
			// GUIObjects.appendChild(GUIObject);

			Attribute Name = new Attribute("Name", td.nameList.get(i));
			GUIObject.addAttribute(Name);
			Attribute UniqueID = new Attribute("UniqueID", td.uniqueIDList
					.get(i));
			GUIObject.addAttribute(UniqueID);
			Attribute Hwnd = new Attribute("Hwnd", td.hwndList.get(i));
			GUIObject.addAttribute(Hwnd);
			Attribute Location = new Attribute("Location", td.locationList
					.get(i));
			GUIObject.addAttribute(Location);
			Attribute Class = new Attribute("class", td.objectClassList.get(i));
			GUIObject.addAttribute(Class);
			Attribute Style = new Attribute("Style", td.styleList.get(i));
			GUIObject.addAttribute(Style);
			Attribute ExtStyle = new Attribute("ExtStyle", td.extStyleList
					.get(i));
			GUIObject.addAttribute(ExtStyle);
			Attribute Role = new Attribute("Role", td.roleList.get(i));
			GUIObject.addAttribute(Role);

			Attribute ConceptName = new Attribute("CName", conceptTable
					.getValueAt(i, 0).toString());
			GUIObject.addAttribute(ConceptName);

			Attribute AltName = new Attribute("AltName", conceptTable
					.getValueAt(i, 8).toString());
			GUIObject.addAttribute(AltName);
			GUIObjects.appendChild(GUIObject);

		}
		Document doc = new Document(root);

		String docText = doc.toXML();
		//File f = new File("GUIObjects.xml");
		Writer out = new BufferedWriter(new OutputStreamWriter(
				new FileOutputStream(xmlFile), "UTF-8"));
		// FileOutputStream fop=new FileOutputStream(f);

		out.write(docText);
		out.flush();
		out.close();

	}

	public static void main(String args[]) {

		// System.out.println(dataList.get(10));
		LookAndFeel lf = UIManager.getLookAndFeel();

		// Install a different look and feel; specifically, the Windows look and
		// feel
		try {
			UIManager
					.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
		} catch (InstantiationException e) {
		} catch (ClassNotFoundException e) {
		} catch (UnsupportedLookAndFeelException e) {
		} catch (IllegalAccessException e) {
		}

		GUIConceptPanel oframe = new GUIConceptPanel();
		oframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		oframe.setVisible(true);
	}

	@Override
	public void tableChanged(TableModelEvent arg0) {
		// TODO Auto-generated method stub
		
	}

}